﻿#ifndef HONG_ASSERT_H
#define HONG_ASSERT_H

#include <assert.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#if defined(__MSC_VER) //可以手动修改这里为/__MSC_VER/__MINGW32__用于调试
    #define SELECT_WINDOWS
#endif


#ifdef SELECT_WINDOWS
#include <windows.h>
#endif

void SafeAbort(const char *errMsg);

#define BASE_ASSERT(x) \
	do \
	{ \
		if (!(x)) \
		{ \
			fprintf(stderr, "Assertion failed: %s (%s:%d)\n", #x, __FILE__, __LINE__); \
		} \
	} while (false)

#ifdef SELECT_WINDOWS
// 将GetLastError对应的错误代码转换为错误信息
void  WinError(char *buffer, size_t bufferSize);

// Windows下的GetLastError样式的错误断言
#define WIN_ASSERT(x) \
	do \
	{ \
		if (!(x)) \
		{ \
			char errStr[256]; \
			fprintf(stderr, "Assertion failed: %s (%s:%d)\n", errStr, __FILE__, __LINE__); \
		} \
	} while (false)

// windows下errno样式的错误断言
#define ERRNO_ASSERT(x) \
	do \
	{ \
		if (!(x)) \
		{ \
			char errStr[256]; \
			strerror_s(errStr, 256, errno); \
			fprintf(stderr, "%s (%s:%d)\n", errStr, __FILE__, __LINE__); \
		} \
	} while (false)

#else
// Linux下errno样式的错误断言
#define ERRNO_ASSERT(x) \
	do \
	{ \
		if (!(x)) \
		{ \
			const char *errStr = strerror(errno); \
			fprintf(stderr, "%s (%s:%d)\n", errStr, __FILE__, __LINE__); \
		} \
	} while (false)

#endif

// POSIX样式的错误断言
#define POSIX_ASSERT(x) \
	do \
	{ \
		if (x) \
		{ \
			const char *errStr = strerror(x); \
			fprintf(stderr, "%s (%s:%d)\n", errStr, __FILE__, __LINE__); \
		} \
	} while (false)


// 内存分配失败的断言
#define ALLOC_ASSERT(x) \
	do \
	{ \
		if (!(x)) \
		{ \
			fprintf(stderr, "FATAL ERROR: OUT OF MEMORY (%s:%d)\n", \
			__FILE__, __LINE__); \
		}\
	} while (false)

#endif//HONG_ASSERT_H
